package cn.xuqiudong.rpc.spring.provider;

import cn.xuqiudong.rpc.common.model.XqdUrl;
import cn.xuqiudong.rpc.protocol.Protocol;
import cn.xuqiudong.rpc.spring.annotation.XqdService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import cn.xuqiudong.rpc.extension.XqdExtensionFactory;
import cn.xuqiudong.rpc.registry.RegistrySingle;

import java.net.InetAddress;
import java.net.UnknownHostException;


/**
 * 描述:  启动protocol（NettyServer）  对于提供者service注册到spring之后的其他处理：如添加到注册中心
 * <p>
 *     BeanPostProcessor，然后对所有的bean进行一个初始化之前/之后的代理
 *
 * </p>
 * @author Vic.xu
 * @date 2022-02-24 17:05
 */
public class XqdSpringProviderBeanProcessor implements InitializingBean, BeanPostProcessor {


    private static org.slf4j.Logger logger = LoggerFactory.getLogger(XqdSpringProviderBeanProcessor.class);

    public XqdSpringProviderBeanProcessor(int serverPort) throws UnknownHostException {
        this.serverPort = serverPort;
        this.serverAddress = InetAddress.getLocalHost().getHostAddress();

    }

    /**
     * RPC的Server端的端口
     */
    private int serverPort;

    /**
     * rpc  的server端的host， 取自当前地址
     */
    private String serverAddress;


    /**
     * 初始化bean的时候执行，启动RPC的Server服务
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        Protocol protocol = XqdExtensionFactory.defaultExtendFactory().getAdaptiveXqdExtension(Protocol.class);
        //新建 Server线程，并设为守护线程
        Thread protocolThread =  new Thread(() -> {
            try {
                protocol.start(serverPort);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        protocolThread.setDaemon(true);
        protocolThread.start();

    }

    /**
     * 在bean初始化完成之后的后置处理器， 若被标志为 {@link XqdService}  则向注册中心开始注册
     * @param bean bean
     * @param beanName beanName
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class beanClass = bean.getClass();
        if (!beanClass.isAnnotationPresent(XqdService.class)) {
            return bean;
        }
        //暂未处理多接口的问题 FIXME
        String interfaceName = beanClass.getInterfaces()[0].getName();
        XqdUrl url = new XqdUrl(serverAddress, serverPort, interfaceName);
        // 保留对其引用
        XqdServiceHolder.putBean(interfaceName, bean);
        //注册到注册中心
        RegistrySingle.getRegistry().register(url);
        return bean;
    }
}
